﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Markup;
using Creventive.Wpf.ShellFactory.Workspace.Primitives;

namespace Creventive.Wpf.ShellFactory.Workspace
{
    /// <summary>
    ///   Represents the simplest form of URI source, one based on nothing else but an URI.
    /// </summary>
    [ContentProperty("Uri")]
    public class ApplicationViewSource : Freezable, IApplicationViewSource
    {
        #region Static Fields/Constants

        /// <summary>
        /// Backing field for the Uri dependency property
        /// </summary>
        public static readonly DependencyProperty UriProperty = DependencyProperty.Register("Uri", typeof(Uri), typeof(ApplicationViewSource), new UIPropertyMetadata(null, (s, e) => ((ApplicationViewSource)s).OnUriChanged((Uri)e.OldValue, (Uri)e.NewValue)));

        #endregion

        private ApplicationView view;

        /// <summary>
        ///   Initializes a new instance of the <see cref = "ApplicationViewSource" /> class.
        /// </summary>
        public ApplicationViewSource()
        {}

        /// <summary>
        ///   Initializes a new instance of the <see cref = "ApplicationViewSource" /> class.
        /// </summary>
        /// <param name = "uri">The URI to load the application view from.</param>
        public ApplicationViewSource(Uri uri)
        {
            this.Uri = uri;
        }

        /// <summary>
        ///   Initializes a new instance of the <see cref = "ApplicationViewSource" /> class.
        /// </summary>
        /// <param name = "view">The view.</param>
        public ApplicationViewSource(ApplicationView view)
        {
            this.view = view;
            this.view.Closed += this.view_Closed;
        }

        /// <summary>
        ///   Gets or sets the URI to load the application view from.
        /// </summary>
        /// <value>The URI.</value>
        public Uri Uri
        {
            get { return (Uri)this.GetValue(UriProperty); }
            set { this.SetValue(UriProperty, value); }
        }

        private void view_Closed(object sender, EventArgs e)
        {
            this.view.Closed -= this.view_Closed;
            this.view = null;
        }

        /// <summary>
        ///   Called when the Uri property changes.
        /// </summary>
        /// <param name = "oldValue">The old value.</param>
        /// <param name = "newValue">The new value.</param>
        protected virtual void OnUriChanged(Uri oldValue, Uri newValue)
        {}

        /// <summary>
        ///   When implemented in a derived class, creates a new instance of the <see cref = "T:System.Windows.Freezable" /> derived class.
        /// </summary>
        /// <returns>The new instance.</returns>
        protected override Freezable CreateInstanceCore()
        {
            return new ApplicationViewSource();
        }

        /// <summary>
        ///   Loads the application view referred to by this view source.
        /// </summary>
        /// <returns></returns>
        public virtual ApplicationView Load()
        {
            if (this.view != null)
                return this.view;
            else if (this.Uri != null)
                return ApplicationView.FromUri(this.Uri);
            else
                return null;
        }
    }
}